﻿using System;
using System.Collections.Generic;
using System.Windows.Forms;
using DigitalRune.Windows.Docking;
using md.imi.membranes.gui.Editor;
using md.imi.membranes.gui.elements;
using md.imi.membranes.objects;
using md.imi.membranes.objects.membranes;

namespace md.imi.membranes.gui.Navigation
{
    /// <summary>
    ///     Show available solutions
    /// </summary>
    public partial class AvailableTransitions : DockableForm
    {
        #region Public events

        // public delegate void SolutionSelectionHandler(Solution solution);
        public delegate void SolutionsSelectionHandler(List<Solution> solution);
        public event SolutionsSelectionHandler NotifySolutionsSelection;

        #endregion Public events

        public AvailableTransitions()
        {
            InitializeComponent();
        }

        public void PopulateSolutions(List<List<Solution>> solutions)
        {
            treeSolutions.Nodes.Clear();

            if (solutions == null)
            {
                return;
            }

            // create root nodes from 1'st level items
            foreach (var solutionsItem in solutions)
            {
                var rootNode = new TreeNode()
                {
                    Text = Solution.GenerateRooSolutionTitle(solutionsItem),
                    Tag = solutionsItem
                };

                treeSolutions.Nodes.Add(rootNode);

                foreach (var subSolutionItem in solutionsItem)
                {
                    var node = new TreeNode()
                    {
                        Text = subSolutionItem.ToString(),
                        Tag = subSolutionItem
                    };

                    rootNode.Nodes.Add(node);
                }
            }
        }

        /// <summary>
        ///     Called when a PSystem's associated editor is selected
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="eventArgs"></param>
        public void UpdatePsystemSelection(object sender, EventArgs eventArgs)
        {
            if (sender == null || !(sender is CurrentConfiguration))
            {
                PopulateSolutions(null);
                return;
            }

            var editorForm = sender as CurrentConfiguration;
            PopulateSolutions(editorForm.Project.Solutions);
            
			TabText = String.Format("AvailableTransitions-{0}", editorForm.Project.ProjectName);
        }

        /// <summary>
        ///     Update of selected membrane should result in selection of solutions branch
        /// which is associated with selected membrane
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="membrane"></param>
        public void UpdateMembraneSelection(MembraneG sender, Membrane membrane)
        {
            // throw new NotImplementedException();
        }

        /// <summary>
        ///     Recursively set nodes status
        /// </summary>
        /// <param name="node"></param>
        /// <param name="nodeStatus"></param>
        private void SetNodesStatus(TreeNode node, bool nodeStatus)
        {
            if (node == null || node.Nodes == null)
            {
                return;
            }

            foreach (TreeNode nodeItem in node.Nodes)
            {
                nodeItem.Checked = nodeStatus;
                SetNodesStatus(nodeItem, nodeStatus);
            }
        }

        /// <summary>
        ///     unmark all nodes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lblMarkAll_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            foreach (TreeNode node in treeSolutions.Nodes)
            {
                node.Checked = true;
                SetNodesStatus(node, true);
            }
        }

        /// <summary>
        /// Mark All Nodes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lblUnmarkAll_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            foreach (TreeNode node in treeSolutions.Nodes)
            {
                node.Checked = false;
                SetNodesStatus(node, false);
            }
        }

        private void treeSolutions_AfterCheck(object sender, TreeViewEventArgs e)
        {
            SetNodesStatus(e.Node, e.Node.Checked);
        }

        /// <summary>
        ///     When a item is selected, higlight the solution parts on membranes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeSolutions_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (NotifySolutionsSelection != null)
            {
                if (e.Node.Tag is Solution)
                {
                    // NotifySolutionSelection((Solution)e.Node.Tag);

                    var solutions = new List<Solution>();
                    solutions.Add((Solution)e.Node.Tag);

                    NotifySolutionsSelection(solutions);
                }
                else if (e.Node.Tag is List<Solution>)
                {
                    NotifySolutionsSelection((List<Solution>)e.Node.Tag);
                }
            }
        }
    }
}